//
//  GCD+Extension.swift
//  Sevengrass
//
//  Created by Kipp Dev on 2017/12/17.
//  Copyright © 2017年 Syrena. All rights reserved.
//

import Foundation

extension DispatchQueue {

    // MARK: - dispatch once 实现
    fileprivate static var _onceTracker = [String]()

    /// 执行一次的方法对应 OC-GCD Once方法
    ///
    /// - Parameters:
    ///   - file: 默认
    ///   - function: 默认
    ///   - line: 默认
    ///   - callback: 执行闭包
    public static func once(file: String = #file, function: String = #function, line: Int = #line, callback:() -> Void) {
        let token = file + ":" + function + ":" + String(line)
        once(token: token, callback: callback)
    }

    public static func once(token: String, callback:() -> Void) {
        objc_sync_enter(self)
        defer { objc_sync_exit(self) }

        if _onceTracker.contains(token) {
            return
        }
        _onceTracker.append(token)
        callback()

    }
}

typealias DelayTask = (_ cancel: Bool) -> Void

/// 延迟执行方法
///
/// - Parameters:
///   - time: 延迟时间
///   - task: 闭包
/// - Returns: 延迟执行任务对象
@discardableResult
func delay(_ time: TimeInterval, task: @escaping () -> Void) -> DelayTask? {

    func dispatch_Later(block: @escaping () -> Void) {
        DispatchQueue.main.asyncAfter(deadline: .now() + time, execute: block)
    }

    var closure: (() -> Void)? = task
    var result: DelayTask?

    let delayedClosure: DelayTask = {
        cancel in
        if let internalClosure = closure {
            if (cancel == false) {
                DispatchQueue.main.async(execute: internalClosure)
            }
        }
        closure = nil
        result = nil
    }

    result = delayedClosure

    dispatch_Later {
        if let delayedClosure = result {
            delayedClosure(false)
        }
    }

    return result
}

/// 取消延迟执行的方法
///
/// - Parameter task: 延迟执行对象
func cancel(_ task:DelayTask?) {
    task?(true)
}
